package com.zhiyou100.review.day012;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.Character.getNumericValue;

/**
 * @packageName: MyStringHomeWork
 * @className: com.zhiyou100.review.day012
 * @Description: TODO String homework
 * @author: yang
 * @date: 6/18/20
 */


public class MyStringHomeWork {
    /**
     * @Description: TODO 获取s中c出现的次数
     * @name: getCiShu
     * @param: [s, c]
     * @return: int
     * @date: 6/18/20 14:33
     * @author: yang
     */
    public static int getCiShu(String s, char c) {
        int cnt = 0;
        int index = -1;
        do {
            cnt++;
            index = s.indexOf(c, index + 1);
        } while (index != -1);
        return cnt - 1;
    }


    /**
     * @Description: TODO  对s进行转换  大写转换为小写 小写转换为大写 删除数字
     * @name: changeStr
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 14:37
     * @author: yang
     */
    public static String changeStr(String s) {
        StringBuilder out = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 'a' && c <= 'z') {
                // 如果是小写，转换为大写
                out.append(String.valueOf(c).toUpperCase());
            } else if (c >= 'A' && c <= 'Z') {
                // 如果是大写，转换为大写
                out.append(String.valueOf(c).toLowerCase());
            } else if (c >= '0' && c <= '9') {
                // 啥也不干
            } else {
                // 其他情况，添加到out中
                out.append(c);
            }
        }
        return out.toString();
    }


    /**
     * @Description: TODO  功能类似于compareTo方法
     * @name: biJiao
     * @param: [s1, s2]
     * @return: int
     * @date: 6/18/20 14:40
     * @author: yang
     */
    public static int biJiao(String s1, String s2) {
        int minLength = Math.min(s1.length(), s2.length());
        // 获取最短的字符串的长度

        for (int i = 0; i < minLength; ++i) {
            char c1 = s1.charAt(i);
            char c2 = s2.charAt(i);
            // 获取 i 位置处的字符

            if (c1 != c2) {
                return c1 - c2;
            }
        }
        return s1.length() - s2.length();
    }

    /**
     * @name: addZero
     * @param: int num
     * @description: TODO  把 1 变成 01
     * @date: 2020/2/21 5:43 下午
     * @return: String
     */
    public static String addZero(int num) {

        int theUnit = 10;
        if (num / theUnit == 0) {
            // 1/10 =  0，是个位
            return "0" + num;
        } else {
            return String.valueOf(num);
            // Int -> String
        }
    }

    /**
     * @name: judgeTheDaysOfTheMonth
     * @param: int year ,int month
     * @description: TODO  判断本月有多少天
     * @date: 2020/2/21 5:00 下午
     * @return: int
     */
    public static int judgeTheDaysOfTheMonth(int year, int month) {

        boolean yearLag = (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
        // yearLag true为闰年，false为平年
        /*
         * 平年的2月份是28天
         * 闰年的2月份是29天
         */
        int maxDay;
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                maxDay = 31;
                break;
            case 2:
                if (yearLag) {
                    maxDay = 29;
                } else {
                    maxDay = 28;
                }
                break;
            default:
                maxDay = 30;
        }
        return maxDay;
    }

    /**
     * @Description: TODO  s格式是xxxx-xx-xx 获取s对应的日期加10天后的日期 如：1234-12-10 ---->1234-12-20
     * @name: getDays
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 15:20
     * @author: yang
     */
    public static String getDays(String s) {
        // s 格式 xxxx-xx-xx
        int one = s.indexOf('-');
        int two = s.lastIndexOf('-');
        int start = 4;
        int end = 7;
        int cnt = 10;
        if (one == start && two == end) {
            // 找到了 两个 -
            String year = s.substring(0, 4);
            String month = s.substring(5, 7);
            String day = s.substring(8, 10);

            int maxDay = judgeTheDaysOfTheMonth(Integer.parseInt(year), Integer.parseInt(month));
            // 获取本月的最大天数

            if ((Integer.parseInt(day) + cnt) <= maxDay) {
                // 如果 day+10 小于等于 本月的最大天数，直接返回一个字符串
                return year + "-" + month + "-" + (Integer.parseInt(day) + 10);
            } else {
                // 不能直接 +10
                if (Integer.parseInt(month) + 1 <= 12) {
                    // 判断月份是否能 +1
                    day = String.valueOf(10 - (maxDay - Integer.parseInt(day)));
                    return year + "-" + addZero(Integer.parseInt(month) + 1) + "-" + addZero(Integer.parseInt(day));
                    // into 2020-6-28
                    // out 2020-7-8
                } else {
                    // 月份不能直接 +1
                    // into 2020-12-30;
                    // out 2021-1-9
                    day = String.valueOf(10 - (maxDay - Integer.parseInt(day)));
                    return (Integer.parseInt(year) + 1) + "-" + "01" + "-" + addZero(Integer.parseInt(day));
                }
            }


        } else {
            throw new RuntimeException("日期格式错误：：xxxx-xx-xx");
        }


    }


    /**
     * @Description: TODO   获取参数字符串s中所有数字字符组成的最大整数 如：abc1uy23p1----->3211
     * @name: getInt
     * @param: [s]
     * @return: int
     * @date: 6/18/20 15:21
     * @author: yang
     */
    public static int getInt(String s) {
        int[] charsArray = new int[s.length()];
        // 创建一个数组用来放提取出来的数字
        int charTag = 0;
        // 数组下标，每次加一
        for (int i = 0; i < s.length(); i++) {
            // 提取字符串中的数字到数组
            char charInString = s.charAt(i);
            if (charInString >= '0' && charInString <= '9') {
                // 找到了数字 ，放入数组，下标+1
                int a = getNumericValue((int) charInString);
                charsArray[charTag++] = a;
            }
        }
        int charNot32 = 0;
        // charNot32 是 放数字数组的大小
        for (int i = charsArray.length - 1; i >= 0; i--) {
            // 倒着找第一个非空的下标
            if (charsArray[i] != '\0') {
                charNot32 = i;
                break;
            }
        }
        Integer[] charsArrayNew = new Integer[charTag];
        // 下标+1
        // 新建一个数组 最大下标是 charsArray的第一个空下标
        for (int i = 0; i < charTag; i++) {
            // 范围 [0,charNot32]
            charsArrayNew[i] = charsArray[i];
            // 把 charsArray 赋给 charsArrayNew
        }
        Arrays.sort(charsArrayNew, Comparator.reverseOrder());
        // 倒着排序
        StringBuilder original = new StringBuilder();
        // 把数组放在字符串中
        for (Integer integer : charsArrayNew) {
            original.append(integer);
            // 拼接
        }
        int intMaxLength = 10;
        if (original.length() >= intMaxLength) {
            //  int max 2147483647, int min -2147483648
            System.out.println("弟弟,int 放不下 ——> int max 2147483647, int min -2147483648");
            System.exit(1);
        }
        return Integer.parseInt(original.toString().trim());
        // 转换为int
    }

    /**
     * @Description: TODO 合并参数字符中的所有叠词
     * @name: mergeReiterative
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 18:08
     * @author: yang
     */
    public static String mergeReiterative(String s) {
        StringBuilder temp = new StringBuilder();
        // 记录结果
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (i == 0) {
                temp.append(c);
            } else {
                char cc = s.charAt(i - 1);
                // 获取上一个字符
                temp.append(cc == c ? "" : c);
                // 如果不重复，则添加到 temp，若重复，不添加
            }
        }
        return temp.toString();
    }

    /**
     * @Description: TODO 打印参数字符中的数字字符，字母字符和其他字符出现的次数
     * @name: printNumberAndLetterAndOther
     * @param: [s]
     * @return: void
     * @date: 6/18/20 18:19
     * @author: yang
     */
    public static void printNumberAndLetterAndOther(String s) {
        int numbers = 0;
        int letter = 0;
        int other = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                // 是否是数字
                numbers++;
            } else if (Character.isLetter(c)) {
                // 是否是字母
                letter++;
            } else {
                // 其他
                other++;
            }
        }
        System.out.println("数字" + numbers + " 字母" + letter + " 其他" + other);
    }

    /**
     * @Description: TODO 翻转字符串
     * @name: flipString
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 18:22
     * @author: yang
     */
    public static String flipString(String s) {

        StringBuilder newString = new StringBuilder();
        for (int i = s.length() - 1; i >= 0; i--) {
            newString.append(s.charAt(i));
        }
        return newString.toString();
    }

    /**
     * @Description: TODO 由参数字符串获取一个新的字符串 如ssssddddiiiiiuuuuuusssedf--->s4d4i5u6s3edf
     * @name: getNewString
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 20:22
     * @author: yang
     */
    public static String getNewString(String s) {
        StringBuilder ss = new StringBuilder();
        // 记录结果
        int cnt = 0;
        // 记录次数
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            // 获取当前 字符
            if (i == 0) {
                // 如果 是第一个字符
                cnt++;
                ss.append(c);
                // 添加到 ss
            } else {
                char cc = s.charAt(i - 1);
                // 获取当前字符 前面的字符
                if (c == cc) {
                    // 如果 当前字符等于前面的字符，次数+1
                    cnt++;
                } else {
                    // 不等于
                    ss.append(cnt > 1 ? cnt : "");
                    // 次数加到 ss
                    ss.append(c);
                    // 当前字符加载进 ss
                    cnt = 1;
                    // 记录当前字符出现的次数
                }
            }
        }
        ss.append(cnt > 1 ? cnt : "");
        return ss.toString();
    }


    /**
     * @Description: TODO myTrim 方法
     * @name: myTrim
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 20:23
     * @author: yang
     */
    public static String myTrim(String s) {

        // " " = 32
        int starterTag = 0;
        // 正数第一个非空格的下标
        int endTag = 0;
        // 倒数第一个非空格的下标
        for (int i = 0; i < s.length(); i++) {
            // 寻找 starterTag 找到就跳出
            if (s.charAt(i) != ' ') {
                starterTag = i;
                break;
            }
        }
        for (int i = s.length() - 1; i >= 0; i--) {
            // 寻找 endTag 找到跳出
            if (s.charAt(i) != ' ') {
                endTag = i;
                break;
            }
        }
        if (starterTag == 0 && endTag == 0) {
            // 若整个字符串都是空格，返回一个空
            return "";
        } else {
            return s.substring(starterTag, endTag + 1);
        }
        // substring 范围是 [str,end)
    }


    /**
     * @Description: TODO 先比较长度 再逐个字符按编码集做比较
     * @name: myCompareTo
     * @param: [s1, s2]
     * @return: int
     * @date: 6/18/20 20:35
     * @author: yang
     */
    public static int myCompareTo(String s1, String s2) {

        int tag = 0;
        if (s1.length() > s2.length()) {
            // 若 1比2长
            tag = 1;
        } else if (s1.length() < s2.length()) {
            // 若 2比1长
            tag = -1;
        } else {
            // 长度一样，按编码表比较
            for (int i = 0; i < s1.length(); i++) {
                if (s1.charAt(i) > s2.charAt(i)) {
                    tag = 1;
                    break;
                } else if (s2.charAt(i) > s1.charAt(i)) {
                    tag = -1;
                    break;
                }
            }
        }
        return tag;
    }

    /**
     * @Description: TODO 过滤 字符串中的 “性”、“色情”、“爆炸”、“恐怖”、“枪”等，
     * @name: filterSensitiveWords
     * @param: [into]
     * @return: java.lang.String
     * @date: 6/18/20 20:39
     * @author: yang
     */
    public static String filterSensitiveWords(String into) {

        String[] stringArr = {
                "性", "色情", "爆炸", "恐怖", "枪"
        };
        // 把敏感词放一个字符串数组
        for (String s : stringArr) {
            into = into.replace(s, getStarts(s));
        }
        // 遍历敏感词数组，替换
        return into;
    }

    /**
     * @Description: TODO 把同样长度的字符 替换为 同样长度的 *
     * @name: getStarts
     * @param: [s]
     * @return: java.lang.String
     * @date: 6/18/20 20:36
     * @author: yang
     */
    public static String getStarts(String s) {
        return "*".repeat(s.length());
    }


    /**
     * @Description: TODO 用户名长度大于等于6位，必须包含数字和英文字母 密码长度大于等于8位，必须包含特殊符合_或者$，英文字母以及数字
     * @name: determineIfTheRegistrationWasSuccessful
     * @param: [name, pwd]
     * @return: boolean
     * @date: 6/18/20 21:35
     * @author: yang
     */
    public static boolean determineIfTheRegistrationWasSuccessful(String name, String pwd) {

        boolean nameLengthFlag = name.length() >= 6;
        // name长度
        boolean pwdLengthFlag = pwd.length() >= 8;
        // pwd长度
        boolean capitalFlag = false;
        // 大写字母
        boolean lowercaseFlag = false;
        // 小写字母
        boolean numberFlag = false;
        // 数字
        boolean finalFlag = false;
        // 是否包含 字母(大写或小写)和数字
        for (int i = 0; i < pwd.length(); i++) {
            char tempChar = pwd.charAt(i);
            boolean lowercaseFlagIn = tempChar >= 'a' && tempChar <= 'z';
            // 判断是否包含小写字母
            boolean capitalFlagIn = tempChar >= 'A' && tempChar <= 'Z';
            // 判断是否包含大写字母
            boolean numberFlagIn = tempChar >= '0' && tempChar <= '9';
            // 判断是否包含数字
            if (lowercaseFlagIn) {
                lowercaseFlag = true;
                continue;
            }
            if (capitalFlagIn) {
                capitalFlag = true;
                continue;
            }
            if (numberFlagIn) {
                numberFlag = true;
            }
        }
        finalFlag = ((capitalFlag || lowercaseFlag) && numberFlag);
        // 若 同时包含 大、小写字母和数字，返回true
        return finalFlag && nameLengthFlag && pwdLengthFlag;
    }

    /**
     * @Description: TODO 写一个方法  有参数字符串获取一个数字组成的字符串数组 如"123kjh123hgfr98jhfgdd876"---{"123","123","98","876"}
     * @name: intoOneStringOutOneIntArray
     * @param: [s]
     * @return: int[]
     * @date: 6/18/20 21:39
     * @author: yang
     */
    public static int[] intoOneStringOutOneIntArray(String s) {

        StringBuilder s1 = new StringBuilder();
        // 创建一个字符串放每个 数字子串
        Pattern p = Pattern.compile("\\d+");
        // 正则匹配 所有数字
        Matcher m = p.matcher(s);
        while (m.find()) {
            // 查找
            s1.append(m.group()).append(" ");
            // 加上一个空格（方便切割），赋给s1 字符串
        }
        String[] strings = s1.toString().split(" ");
        // 用" "，切割，组成新的字符串数组
        int[] arr = new int[strings.length];
        //生成int数组，放处理完成的数字串
        for (int i = 0; i < strings.length; i++) {
            arr[i] = Integer.parseInt(strings[i].trim());
            // 字符串去掉空格后赋值
        }
        return arr;
    }


    public static void digitalBlackHole() {
        // 取任意一个4位数（4个数字均为同一个数的，以及三个数字相同，另外一个数与这个数相差1，如1112，,6566等除外
        int min = 1000;
        int max = 9999;
        int cnt = 0;
        for (int i = min; i <= max; i++) {
            boolean one = determineIfTheNumbersSame(i);
            // 判断4个数字是否全部相同
            boolean two = determineIfTheThreeDigitsAreTheSame(i);
            // 判断 3个 数字是否相同
            if (one || two) {
                System.out.println("不符合条件的数字 " + i + "\n");
            } else {
                // 同时符合 one 和 two ，执行
                cnt++;
                System.out.println(i);
                sixOneSevenFive(i);
            }
        }
        System.out.println("-----------------");
        System.out.println("共判断了 " + cnt + " 个数字，全部成立，所以本结论成立");
    }


    /**
     * @Description: TODO 判断 四个数 中 三个数是否相同, 相同返回 true ，不同返回 false
     * @name: determineIfTheThreeDigitsAreTheSame
     * @param: [num]
     * @return: boolean
     * @date: 6/18/20 23:05
     * @author: yang
     */
    public static boolean determineIfTheThreeDigitsAreTheSame(int num) {
        String s = String.valueOf(num);
        // 转为 int
        boolean flag = false;
        // 记录状态
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            int ciShu = getCiShu(s, c);
            // 判断该字符出现的次数
            if (ciShu == 3) {
                flag = true;
                break;
            } else {
                flag = false;
            }
        }
        return flag;
    }

    public static void sixOneSevenFive(int number) {
        int cardinalNumber = number;
        int sixOneSevenFive = 6174;
        // 卡普雷卡尔（Kaprekar）常数
        int i = 0;
        System.out.println(cardinalNumber + " 开始-------");
        while (number != sixOneSevenFive) {
            i++;
            int max = sortMax(number);
            int min = sortMin(number);
            number = max - min;
            System.out.println(cardinalNumber + " 第" + i + "次 " + max + " - " + min + " = " + number);
        }
        System.out.println(cardinalNumber + " 结束 ------");
        System.out.println();

    }

    /**
     * @Description: TODO 把一个 int 按照 最小 排序
     * @name: sortMin
     * @param: [number]
     * @return: int
     * @date: 6/18/20 22:37
     * @author: yang
     */
    public static int sortMin(int number) {
        String s = String.valueOf(number);
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        return getIntOfCharArray(chars);
    }

    /**
     * @Description: TODO 把 一个 int 按最大值 排序
     * @name: sortMax
     * @param: [number]
     * @return: int
     * @date: 6/18/20 22:36
     * @author: yang
     */
    public static int sortMax(int number) {
        String s = String.valueOf(number);
        char[] chars = s.toCharArray();
        Character[] characters = charArrayToCharacterArray(chars);
        Arrays.sort(characters, Collections.reverseOrder());
        char[] chars1 = charactersArraysToCharsArrays(characters);
        return getIntOfCharArray(chars1);
    }

    /**
     * @Description: TODO 把一个char[] 转为 int
     * @name: getIntOfCharArray
     * @param: [chars]
     * @return: int
     * @date: 6/18/20 22:34
     * @author: yang
     */
    public static int getIntOfCharArray(char[] chars) {
        return Integer.parseInt(String.valueOf(chars));
    }

    /**
     * @Description: TODO 把 character[] 类型的数组 转为 char[] 类型的数组
     * @name: charactersArraysToCharsArrays
     * @param: [characters]
     * @return: char[]
     * @date: 6/18/20 22:21
     * @author: yang
     */
    public static char[] charactersArraysToCharsArrays(Character[] characters) {
        char[] chars = new char[characters.length];

        for (int i = 0; i < characters.length; i++) {
            chars[i] = characters[i];
        }

        return chars;
    }

    /**
     * @Description: TODO  把 char[] 类型的数组，转为 Character[] 类型的数组
     * @name: charArrayToCharacterArray
     * @param: [chars]
     * @return: java.lang.Character[]
     * @date: 6/18/20 22:21
     * @author: yang
     */
    public static Character[] charArrayToCharacterArray(char[] chars) {
        Character[] characters = new Character[chars.length];

        for (int i = 0; i < chars.length; i++) {
            characters[i] = chars[i];
        }

        return characters;

    }

    /**
     * @Description: TODO 判断一个数字是否全部相同，完全相同返回 true，否则返回 false
     * @name: determineIfItSTheSame
     * @param: [number]
     * @return: boolean
     * @date: 6/18/20 21:53
     * @author: yang
     */
    public static boolean determineIfTheNumbersSame(int number) {
        String s = String.valueOf(number);
        boolean flag = false;
        for (int i = 0; i < s.length() - 1; i++) {
            if (s.charAt(i) != s.charAt(i + 1)) {
                flag = false;
                break;
            } else {
                flag = true;
            }
        }
        return flag;
    }


}
